iconEuler Examples

The Koch Curve

This is an example of a fractal, generated recursively. We use simple plot commands, holding the current graphics.

>A=[cos(pi/3),-sin(pi/3);sin(pi/3),cos(pi/3)];
>B=inv(A);
>function koch (x,v,n) ...
   global A,B;
   if n==0 then
     hold on;
     plot([x[1],x[1]+v[1]],[x[2],x[2]+v[2]]);
     hold off;
   else
     w=v/3;
     koch(x,w,n-1); x=x+w;
     w1=A.w; koch(x,w1,n-1); x=x+w1;
     w1=B.w; koch(x,w1,n-1); x=x+w1;
     koch(x,w,n-1);
   endif;
 endfunction

One level deep, the Curve looks like this.

>plot2d(none,a=0,b=1,c=0,d=1); ...
 koch([0;0],[1;1],2):

Koch Curve

Several levels deep, we relace every straight line with one curve of the same shape over and over again.

The work grows exponentially. n=7 is about the most, Euler can do.

>plot2d(none,a=0,b=1,c=0,d=1); ...
 koch([0;0],[1;1],7):

Koch Curve

Dragon Curve

In fact, the generation of a fractal is much faster in Python. Moreover, Python has growing lists. Euler has such lists too, but you would need to import a C library for this.

But notice that the plotting takes the most time whatever you do.

>function python ...
 import math;
 x,y = 0,0
 vx=[x]
 vy=[y]
 
 def fd (delta,alpha):
   global x,y,vx,vy
   x=x+delta*math.cos(alpha*math.pi/180)
   y=y+delta*math.sin(alpha*math.pi/180)
   vx.append(x)
   vy.append(y)
   
 def dragonrek (delta,alpha,n,left):
   if n==0:
     fd(delta,alpha)
   else:
     signum=2*left-1
     dragonrek(delta/math.sqrt(2),alpha+signum*45,n-1,False)
     dragonrek(delta/math.sqrt(2),alpha-signum*45,n-1,True)
 
 def dragon (n):
   global x,y,vx,vy;
   x,y=-1,0
   vx=[x]
   vy=[y]
   dragonrek(2.0,0,n,False)
   return [vx,vy]
 
 endfunction
>v=py$dragon(12); ...
 fullwindow(); ...
 plot2d(v[1],v[2],a=-1.7,b=1.5,c=-2,d=1.2,grid=0):

Koch Curve

Let us take the challenge in Euler. We need global values as in Python for an efficient implementation. Expanding and returning an Euler vector in each call to fd would be very slow. And we do not want to use Euler's global lists.

>function fd (delta, alpha) ...
 global x,y,V,Vn
 x=x+delta*cos(rad(alpha));
 y=y+delta*sin(rad(alpha));
 Vn=Vn+1;
 V[1,Vn]=x;
 V[2,Vn]=y;
 endfunction

These functions are very similar to the Python implementation.

>function dragonrek (delta,alpha,n,signum) ...
 if n==0 then fd(delta,alpha);
 else
     dragonrek(delta/sqrt(2),alpha+signum*45,n-1,-1);
     dragonrek(delta/sqrt(2),alpha-signum*45,n-1,1);
 endif;
 endfunction

Now we define the global variables, setting V large enough.

>x=-1; y=0; n=12; V=zeros(2,2^(n+1)); Vn=1; V[1,1]=x; V[2,1]=y; ...
 tic; dragonrek(2,0,n,-1); toc;
Used 0.102 seconds

I told you, that Python would be faster.

>tic; py$dragon(n); toc;
Used 0.008 seconds

But the plot takes most of the time.

>tic; plot2d(V[1,1:Vn],V[2,1:Vn],a=-1.7,b=1.5,c=-2,d=1.2,grid=0); toc;
Used 0.55 seconds

Examples